package cmd

import (
	"context"
	"dynamic-private/internal/api"
	"dynamic-private/pkg/base"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/tristin2024/logs"
	"github.com/urfave/cli/v2"
	"go.uber.org/fx"
)

func Run(ctx *cli.Context) error {
	app := fx.New(
		fx.NopLogger,
		fx.Provide(
			ginProvide,
			postgresqlProvide,
			redisProvide,
		),
		fx.Populate(
			&base.GinEngine,
			&base.XormEngine,
			&base.RedisEngine,
		),
		fx.Invoke(api.InitRouter),
	)
	if err := app.Start(ctx.Context); err != nil {
		logs.Std.Errorf("启动服务错误: %s", err.Error())
		return err
	}
	server := &http.Server{
		Addr:    fmt.Sprintf("%s:%d", ctx.String("ip"), ctx.Int("port")),
		Handler: base.GinEngine,
	}
	go func() {
		logs.Std.Debugf("listen on: %s", server.Addr)
		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			panic("启动异常: " + err.Error())
		}
	}()
	shutdown(func() {
		_ = server.Shutdown(context.Background())
		logs.Std.Warnf("http server stop")
		stopCtx, cancel := context.WithTimeout(context.Background(), 15*time.Hour)
		defer cancel()
		_ = app.Stop(stopCtx)
	})
	return nil
}

func shutdown(f func()) {
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
	s := <-quit
	logs.Std.Warnf("====================收到停止信号[%v]=====================", s)
	f()
	time.Sleep(time.Second * 3)
}
